//
//  NADAMobileIOHelper.m
//
//  Created by Brian on 7/14/09.
//  Copyright 2009 Tellart. All rights reserved.
//

#import "Socket.h"
#import "NADAMobileIOHelper.h"

#define kMusicPlayer [MPMusicPlayerController iPodMusicPlayer]


@implementation NADAMobileIOHelper

@synthesize myDelegate, audioPlayer, videoPlayer, musicPlayer;


//set up the NADAMobileIOHelper
-(id)init
{
    if (self = [super init])
    {
        NSLog(@"[NADAMobileIOHelper init]");

        soundIds = [NSMutableDictionary dictionaryWithCapacity:5];
        [soundIds retain];

        networkQueue = [[ASINetworkQueue alloc] init];
        [networkQueue retain];
        [networkQueue setDelegate:self];
        
        peerMessenger = [[P2PMessenger alloc] init];
        [peerMessenger retain];
      
    }
    return self;
}

//deallocate the NADAMobileIOHelper
- (void)dealloc {
    NSLog(@"[NADAMobileIOHelper dealloc]");
    [networkQueue release];
    [self disable];
    [soundIds release];
    
    if (self.audioPlayer) [self stopAllSounds];
    [audioPlayer release];
    
    if (self.videoPlayer) [self stopAllVideos];
    //[videoPlayer release];
    self.videoPlayer = nil;
    
    self.musicPlayer = nil;
    
    [peerMessenger release];
    
    [super dealloc];
}

/*******************************************************************************************************************
 *
 * lifecycle control functions
 *
 */

- (void) enableWithDelegate:(id <NADAMobileIOHelperDelegate>)delegate
    useLocation:(BOOL)useLocation
    useAccelerometer:(BOOL)useAccelerometer
    useAudio:(BOOL)useAudio:(BOOL)generateCarrierTone:(NSString*)carrierToneFilePath
    useProximity:(BOOL)useProximity
    useOrientation:(BOOL)useOrientation
    useBattery:(BOOL)useBattery
    useIPodRemote:(BOOL)useIPodRemote
    //useCamera:(BOOL)useCamera
{
    [self setDelegate:delegate];
    NSLog(@"NADAMobileIOHelper: enabling...");
    if (useLocation) [self enableSensorLocation];
    if (useAccelerometer) [self enableSensorAccelerometer];
    if (useAudio) [self enableSensorAudioAmplitude:generateCarrierTone withSampleFile:(NSString*)carrierToneFilePath];
    if (useProximity) [self enableSensorProximity];
    if (useOrientation) [self enableSensorOrientation];
    if (useBattery) [self enableSensorBattery];
    if (useIPodRemote) [self enableSensorIPodRemote];
    //if (useCamera) [self enableSensorCamera];
}

- (void) setDelegate:(id <NADAMobileIOHelperDelegate>)delegate {
    myDelegate = delegate;
}

- (id <NADAMobileIOHelperDelegate>) getDelegate {
    return myDelegate;
}

- (BOOL) getEnabled {
    return sensorAccelerometerEnabled || sensorLocationEnabled || sensorAudioAmplitudeEnabled;
}

- (void) disable {
    NSLog(@"NADAMobileIOHelper: disabling...");
    [self disableSensorLocation];
    [self disableSensorAccelerometer];
    [self disableSensorAudioAmplitude];
    [self disableSensorProximity];
    [self disableSensorOrientation];
    [self disableSensorBattery];
    [self disableSensorIPodRemote];
    //[self disableSensorCamera];
}

/*******************************************************************************************************************
 *
 * Accelerometer
 *
 */

// set up to receive accelerometer notifications
- (void)enableSensorAccelerometer {
    NSLog(@"NADAMobileIOHelper: enableSensorAccelerometer");
    if (sensorAccelerometerEnabled == NO) {
        NSLog(@"NADAMobileIOHelper: enableSensorAccelerometer: enabling accelerometer...");
        [[UIAccelerometer sharedAccelerometer] setUpdateInterval:kAccelerometerPeriod];
        [[UIAccelerometer sharedAccelerometer] setDelegate:self];
        //make sure we don't do this more than once:
        sensorAccelerometerEnabled = YES;
    }
}
// stop receiving accelerometer notifications
- (void)disableSensorAccelerometer {
    NSLog(@"NADAMobileIOHelper: disableSensorAccelerometer");
    if (sensorLocationEnabled == YES) {
        NSLog(@"NADAMobileIOHelper: disableSensorAccelerometer: disabling accelerometer...");
        sensorAccelerometerEnabled = NO;
        
        //perform cleanup
        [[UIAccelerometer sharedAccelerometer] setDelegate:nil];
        
    }
}
// process notifications from the accelerometer
- (void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration {
    //NSLog(@"NADAMobileIOHelper: accelerometer didAccelerate");
    [myDelegate nada:self didAccelerate:acceleration];
    
}

/*******************************************************************************************************************
 *
 * Location and heading
 *
 */

// set up to receive core location notifications
- (void)enableSensorLocation {
    NSLog(@"NADAMobileIOHelper: enableSensorLocation");
    if (sensorLocationEnabled == NO) {
        NSLog(@"NADAMobileIOHelper: enableSensorLocation: enabling location sensor...");
        locationManager = [[CLLocationManager alloc] init];
        [locationManager retain];
        
        locationManager.delegate = self;
        locationManager.desiredAccuracy = kCLLocationAccuracyBest; //kCLLocationAccuracyKilometer;
        locationManager.distanceFilter = 1; //kCLDistanceFilterNone;
        
        #if __IPHONE_3_0
        locationManager.headingFilter = 0.5; //kCLHeadingFilterNone;
        #endif
        
        //start updating
        [locationManager startUpdatingLocation];
        
        #if __IPHONE_3_0
        [locationManager startUpdatingHeading];
        #endif
        
        //make sure we don't do this more than once:
        sensorLocationEnabled = YES;
    }
}
- (void)disableSensorLocation {
    NSLog(@"NADAMobileIOHelper: disableSensorLocation");
    if (sensorLocationEnabled == YES) {
        NSLog(@"NADAMobileIOHelper: disableSensorLocation: disabling location sensor...");
        sensorLocationEnabled = NO;

        //perform cleanup
        [locationManager release];
        
    }
}
// Receives notifications from CoreLocation when the device location changes
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
		   fromLocation:(CLLocation *)oldLocation
{
	//NSLog(@"Location updated");
    // If it's a relatively recent event, turn off updates to save power
    NSDate* eventDate = newLocation.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
    if (howRecent < -0.0 && howRecent > -10.0) {
        //[manager stopUpdatingLocation]; //hrm, should we call this if we want continuous location updates?
        [myDelegate nada:self didUpdateToLocation:newLocation fromLocation:oldLocation];
    }
    // else skip the event and process the next one.
}

// receives notifications from CoreLocation when the device heading changes
#if __IPHONE_3_0
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
    [myDelegate nada:self didUpdateHeading:newHeading];
}
#endif

// Tell the CLLocationManager whether to display the heading calibration interface
- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager {
    return NO;
}

//location manager failed with an error
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
	NSLog(@"locationManager error: %@", error.localizedDescription);
}


/*******************************************************************************************************************
 * shared by all sensors that get data from UIDevice
 *
 */


/*******************************************************************************************************************
 *
 * Proximity
 *
 */
- (void)enableSensorProximity;
{
    NSLog(@"NADAMobileIOHelper: enableSensorProximity");
    if (sensorProximityEnabled == NO) {
        NSLog(@"NADAMobileIOHelper: enableSensorProximity: enabling proximity sensor...");
        
        [[NSNotificationCenter defaultCenter]
            addObserver:self
            selector:@selector(sensorProximityChanged:)
            name:UIDeviceProximityStateDidChangeNotification object:nil];
        [UIDevice currentDevice].proximityMonitoringEnabled = YES;
        
        sensorProximityEnabled = YES;
    }
}

- (void)disableSensorProximity
{
    NSLog(@"NADAMobileIOHelper: disableSensorProximity");
    if (sensorProximityEnabled == YES) {
        NSLog(@"NADAMobileIOHelper: disableSensorProximity: disabling proximity sensor...");

        //perform cleanup
        [UIDevice currentDevice].proximityMonitoringEnabled = NO;
        
        [[NSNotificationCenter defaultCenter]
            removeObserver:self
            name:UIDeviceProximityStateDidChangeNotification object:nil];

        sensorProximityEnabled = NO;
    }
}

- (void)sensorProximityChanged:(NSNotification *)notification
{
    //NSLog(@"sensorProximityChanged %i", [UIDevice currentDevice].proximityState);
    [myDelegate nada:self didChangeProximity:[UIDevice currentDevice].proximityState];
}


/*******************************************************************************************************************
 *
 * Orientation
 *
 */
- (void)enableSensorOrientation;
{
    NSLog(@"NADAMobileIOHelper: enableSensorOrientation");
    if (sensorOrientationEnabled == NO) {
        NSLog(@"NADAMobileIOHelper: enableSensorOrientation: enabling orientation sensor...");
        
        [[NSNotificationCenter defaultCenter]
            addObserver:self
            selector:@selector(sensorOrientationChanged:)
            name:UIDeviceOrientationDidChangeNotification object:nil];
        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
        
        sensorOrientationEnabled = YES;
    }
}

- (void)disableSensorOrientation
{
    NSLog(@"NADAMobileIOHelper: disableSensorOrientation");
    if (sensorOrientationEnabled == YES) {
        NSLog(@"NADAMobileIOHelper: disableSensorOrientation: disabling orientation sensor...");
        
        //perform cleanup
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
        [[NSNotificationCenter defaultCenter]
            removeObserver:self
            name:UIDeviceOrientationDidChangeNotification object:nil];

        sensorOrientationEnabled = NO;
    }
}

- (void)sensorOrientationChanged:(NSNotification *)notification
{
    //NSLog(@"sensorOrientationChanged");
    [myDelegate nada:self didChangeOrientation:[UIDevice currentDevice].orientation];
}


/*******************************************************************************************************************
 *
 * Battery
 *
 */
- (void)enableSensorBattery;
{
    NSLog(@"NADAMobileIOHelper: enableSensorBattery");
    if (sensorBatteryEnabled == NO) {
        NSLog(@"NADAMobileIOHelper: enableSensorBattery: enabling battery sensor...");
        
        [[NSNotificationCenter defaultCenter]
            addObserver:self
            selector:@selector(sensorBatteryChanged:)
            name:UIDeviceBatteryLevelDidChangeNotification object:nil];
        [UIDevice currentDevice].batteryMonitoringEnabled = YES;
        
        sensorBatteryEnabled = YES;
    }
}

- (void)disableSensorBattery
{
    NSLog(@"NADAMobileIOHelper: disableSensorBattery");
    if (sensorBatteryEnabled == YES) {
        NSLog(@"NADAMobileIOHelper: disableSensorBattery: disabling battery sensor...");

        //perform cleanup
        [UIDevice currentDevice].batteryMonitoringEnabled = NO;
        [[NSNotificationCenter defaultCenter]
            removeObserver:self
            name:UIDeviceBatteryLevelDidChangeNotification object:nil];

        sensorBatteryEnabled = NO;
    }
}

- (void)sensorBatteryChanged:(NSNotification *)notification
{
    NSLog(@"sensorBatteryChanged %f", [UIDevice currentDevice].batteryLevel);
    [myDelegate nada:self didChangeBattery:[UIDevice currentDevice].batteryLevel];
}


/*******************************************************************************************************************
 *
 * Audio
 *
 */
- (void)enableSensorAudioAmplitude:(BOOL)generateCarrierTone withSampleFile:(NSString*)pathToCarrierToneFile
{
    NSLog(@"NADAMobileIOHelper: enableSensorAudioAmplitude");
    if (sensorAudioAmplitudeEnabled == NO) {
        NSLog(@"NADAMobileIOHelper: enableSensorAudioAmplitude: enabling AudioAmplitude... (generateCarrierTone = %d)", generateCarrierTone);
        
        if (! amIO) {
            //amIO = [[AM_IO alloc] init];
            amIO = [[NewAMIO alloc] init];
            [amIO retain];
            [amIO initAudio:pathToCarrierToneFile];
            //[amIO initAudio:generateCarrierTone];
            //id <PeakAmplitudeDelegate> mydelegate = self;
            //amIO.peakAmpDelegate = mydelegate;
        } else {
            //[amIO setCarrierToneGenerator:generateCarrierTone];
            [amIO setCarrierTone:generateCarrierTone];
        }
        
        //make sure we don't do this more than once:
        sensorAudioAmplitudeEnabled = YES;
    }
}

- (void)disableSensorAudioAmplitude {
    NSLog(@"NADAMobileIOHelper: disableSensorAudioAmplitude");
    if (sensorAudioAmplitudeEnabled == YES) {
        NSLog(@"NADAMobileIOHelper: disableSensorAudioAmplitude: disabling AudioAmplitude...");
        sensorAudioAmplitudeEnabled = NO;
        
        //turn off the sine tone when disabling
        //[amIO setSineToneGenerator:NO];
        [amIO setCarrierTone:NO];
        
        //perform cleanup
        //[amIO release];
    }
}

// process audio amplitude info
- (void) updateAmplitudeMonitor {
    if (!sensorAudioAmplitudeEnabled) return;
    //if (amIO.peakAmp == lastPeakAmp) return;
    
    if (amIO.inputAvailable) {
        //each power reading from amIO is in dB, so -160 is total silence and 0 is maximum volume
        //convert each into a fraction between 0 and 1.0, where 1.0 is highest volume
        const NSUInteger channelNumber = 0;
        AMIOAmplitudeValue peak = pow(10, (0.05 * [amIO peakPowerForChannel:channelNumber]));
        AMIOAmplitudeValue avg = pow(10, (0.05 * [amIO averagePowerForChannel:channelNumber]));
        AMIOAmplitudeValue l = [amIO lowpassPowerForChannel:0];
        AMIOAmplitudeValue m = [amIO midrangePowerForChannel:0];
        AMIOAmplitudeValue h = [amIO highpassPowerForChannel:0];
        
        [myDelegate nada:self didUpdateAudioAmplitude:peak average:avg low:l mid:m high:h];
    } else {
        [myDelegate nada:self didUpdateAudioAmplitude:-1.0 average:-1.0 low:-1.0 mid:-1.0 high:-1.0];
    }
    
    lastPeakAmp = [amIO peakPowerForChannel:0];
}

- (void) stopAllSounds
{
    if (self.audioPlayer) {
        NSLog(@"NADAMobileIOHelper: stopAllSounds");
        [audioPlayer stop];
    }
}

- (void)vibrate
{
    NSLog(@"NADAMobileIOHelper vibrate");
    AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}

- (void)playSound:(NSURL*)soundURL
{
    //if (self.audioPlayer) [self stopAllSounds];
    
    if (soundURL == nil) return;
    
    NSError *error = [NSError alloc];
    AVAudioPlayer *p = [[AVAudioPlayer alloc]
        initWithContentsOfURL:soundURL
        error:&error];
      
    if (p) {
        NSLog(@"NADAMobileIOHelper: playSound: playing %@", soundURL);
        [p prepareToPlay];
        [p play];
    } else
        NSLog(@"NADAMobileIOHelper: playSound error: %@", [NSError description]);
    
    self.audioPlayer = p;
    [p release];
}


/*******************************************************************************************************************
 *
 * video
 *
 */
- (void) playVideo:(NSURL*)videoURL
{
    //if (self.videoPlayer) [self stopAllVideos];

    if (videoURL == nil) return;

    MPMoviePlayerController* theMovie = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
    theMovie.scalingMode = MPMovieScalingModeNone;
    theMovie.movieControlMode = MPMovieControlModeHidden;
    
    //register for notification of the video being finished
    
    [[NSNotificationCenter defaultCenter]   addObserver:self
                                            selector:@selector(videoPlayerFinishedCallback:)
                                            name:MPMoviePlayerPlaybackDidFinishNotification
                                            object:theMovie];
    
    theMovie.initialPlaybackTime = 0.0;
    
    //start playback
    [theMovie play];
    
    //keep a reference around so that we can asynchronously stop videos
    self.videoPlayer = theMovie;
    
    //we don't need this reference anymore
    [theMovie release];
}


- (void) stopAllVideos
{
    if (self.videoPlayer) {
        NSLog(@"NADAMobileIOHelper: stopAllVideos");
        [videoPlayer stop];
    }
}

- (void) videoPlayerFinishedCallback:(NSNotification*)aNotification
{
    NSLog(@"videoPlayerFinishedCallback started");
    
    MPMoviePlayerController* theMovie=[aNotification object];
    [[NSNotificationCenter defaultCenter]   removeObserver:self
                                            name:MPMoviePlayerPlaybackDidFinishNotification
                                            object:theMovie];
    //[theMovie release];
    self.videoPlayer = nil;
    
    NSLog(@"videoPlayerFinishedCallback finished");
}


/*******************************************************************************************************************
 *
 * camera
 *
 */
/*
- (void)enableSensorCamera
{
    NSLog(@"NADAMobileIOHelper: enableSensorCamera");
    if (sensorCameraEnabled == NO) {
        NSLog(@"NADAMobileIOHelper: enableSensorCamera: enabling camera...");
        
        sensorCameraEnabled = YES;
    }
}

- (void)disableSensorCamera
{
    NSLog(@"NADAMobileIOHelper: disableSensorCamera");
    if (sensorBatteryEnabled == YES) {
        NSLog(@"NADAMobileIOHelper: disableSensorCamera: disabling camera...");

        //perform cleanup
        [cameraController release];
        self.cameraController = nil;

        sensorCameraEnabled = NO;
    }
}

- (void)prepareCameraCaptureWithViewController:(UIViewController *)vc
{
    if (!sensorCameraEnabled) return;
    NSLog(@"[NADAMobileIOHelper prepareCameraCaptureWithViewController]");
    
    UIImagePickerController* picker = [[UIImagePickerController alloc] init];
    
    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        //no camera available
        [myDelegate nada:self didFinishCameraCapture:nil];
    } else {
        //use the camera
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
    }
    
    picker.cameraOverlayView = vc.view;
    picker.delegate = self;
    picker.showsCameraControls = NO;

    self.cameraController = picker;
    [picker release];
    
    if (vc.parentViewController) {
        [vc.parentViewController presentModalViewController:self.cameraController animated:NO];
    } else {
        [vc presentModalViewController:self.cameraController animated:NO];
    }
}

- (void)beginCameraCapture
{
    //TODO
    
    if (!sensorCameraEnabled) return;
    NSLog(@"[NADAMobileIOHelper beginCameraCapture]");
    [self.cameraController takePicture];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    NSLog(@"NADAMobileIOHelper imagePickerControllerDidCancel");
    [myDelegate nada:self didFinishCameraCapture:nil];
    [picker release];
    self.cameraController = nil;
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSLog(@"NADAMobileIOHelper didFinishPickingMediaWithInfo");
    [myDelegate nada:self didFinishCameraCapture:info];
    [picker release];
    self.cameraController = nil;
}
*/

/*******************************************************************************************************************
 *
 * iPod Remote
 *
 */
- (void)enableSensorIPodRemote
{
    NSLog(@"NADAMobileIOHelper: enableSensorIPodRemote");
    if (sensorIPodRemoteEnabled == NO) {
        NSLog(@"NADAMobileIOHelper: enableSensorIPodRemote: enabling iPod Remote sensor...");

        MPMusicPlayerController *mp = kMusicPlayer;

        if (mp) {
            [[NSNotificationCenter defaultCenter] addObserver:self 
                                   selector:@selector(iPodNowPlayingItemChanged:)
                                       name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification 
                                     object:mp];
            [[NSNotificationCenter defaultCenter] addObserver:self 
                                   selector:@selector(iPodPlaybackStateChanged:)
                                       name:MPMusicPlayerControllerPlaybackStateDidChangeNotification 
                                     object:mp];
            [[NSNotificationCenter defaultCenter] addObserver:self 
                                   selector:@selector(iPodExternalVolumeChanged:)
                                       name:MPMusicPlayerControllerVolumeDidChangeNotification 
                                     object:mp];
            [mp beginGeneratingPlaybackNotifications];
            
            [mp beginGeneratingPlaybackNotifications];
        }
        
        self.musicPlayer = mp;

        sensorIPodRemoteEnabled = YES;
    }
}

- (void)disableSensorIPodRemote
{
    NSLog(@"NADAMobileIOHelper: disableSensorIPodRemote");
    if (sensorIPodRemoteEnabled == YES) {
        NSLog(@"NADAMobileIOHelper: disableSensorIPodRemote: disabling iPod Remote sensor...");

        //perform cleanup
        MPMusicPlayerController *mp = self.musicPlayer;
        
        if (mp) {
            [mp endGeneratingPlaybackNotifications];
            [[NSNotificationCenter defaultCenter] removeObserver:self 
                                       name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification 
                                     object:mp];
            [[NSNotificationCenter defaultCenter] removeObserver:self 
                                       name:MPMusicPlayerControllerPlaybackStateDidChangeNotification 
                                     object:mp];
            [[NSNotificationCenter defaultCenter] removeObserver:self 
                                       name:MPMusicPlayerControllerVolumeDidChangeNotification 
                                     object:mp];
        }
        
        self.musicPlayer = nil;

        sensorIPodRemoteEnabled = NO;
    }
}

- (void)iPodNowPlayingItemChanged:(id)notification
{
    //TODO
    NSLog(@"NADAMobileIOHelper: iPodNowPlayingItemChanged");
}

- (void)iPodPlaybackStateChanged:(id)notification
{
    //NSLog(@"NADAMobileIOHelper: iPodPlaybackStateChanged");
    MPMusicPlayerController *mp = self.musicPlayer;
    MPMusicPlaybackState playbackState = mp.playbackState;
    if (playbackState == MPMusicPlaybackStatePaused || playbackState == MPMusicPlaybackStateStopped) {
        //NSLog(@"NADAMobileIOHelper: iPodPlaybackStateChanged: PLAY");
        //make callback
        [myDelegate nada:self iPodDidChangeStatePlaying:YES paused:NO];
        
    } else if (playbackState == MPMusicPlaybackStatePlaying) {
        //NSLog(@"NADAMobileIOHelper: iPodPlaybackStateChanged: PAUSE");
        //make callback
        [myDelegate nada:self iPodDidChangeStatePlaying:NO paused:YES];
    }
}

- (void)iPodExternalVolumeChanged:(id)notification
{
    //make callback
    MPMusicPlayerController *mp = self.musicPlayer;
    //NSLog(@"NADAMobileIOHelper: iPodExternalVolumeChanged: %f", mp.volume);
    [myDelegate nada:self didChangeIPodVolume:mp.volume];
}


/*******************************************************************************************************************
 *
 * twitpic
 *
 */
- (void)sendTwitpicWithNetworkQueueWithUsername:(NSString*)username /*:(ASINetworkQueue*)queue*/
        andPassword:(NSString*)password
        andMessage:(NSString*)message
        andImage:(UIImage*)image
{
	ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:kTwitpicUploadAndPostURL]] autorelease];
	[request setPostValue:username forKey:@"username"];
	[request setPostValue:password forKey:@"password"];
	[request setPostValue:message forKey:@"message"];
    NSData *data;
    
    //get data from the UIImage
    if (image) {
        data = UIImagePNGRepresentation(image);
        [request setData:data forKey:@"media"];
    }
    
	[networkQueue addOperation:request];
    
    NSLog(@"sendTwitpicWithNetworkQueueWithUsername is going, %@", request);
    
	[networkQueue go];
}

/*******************************************************************************************************************
 *
 * simpleSockets
 *
 */

- (IOHelperSimpleSocketStatus) simpleSocketAccept
{
    NSLog(@"NADAMobileIOHelper: simpleSocketAccept");
    
    if (simpleSocketKeepAccepting) return kIOHelperSimpleSocketStatus_OK; //don't do this more than once

    [NSThread detachNewThreadSelector:@selector(simpleSocketServer:) toTarget:self withObject:nil];
    return kIOHelperSimpleSocketStatus_OK;
}

- (IOHelperSimpleSocketStatus) simpleSocketSendTo:(NSString *)addr message:(NSString *)msg async:(BOOL)a
{
    NSLog(@"NADAMobileIOHelper: simpleSocketSendTo");
    
    Socket *s = [Socket socket];
    
    [s setBlocking:YES];
    [s connectToHostName:addr port:kSimpleSocketTCPPort];
    [s writeData:[msg dataUsingEncoding:NSUTF8StringEncoding]];
    
    return kIOHelperSimpleSocketStatus_OK;
}

- (void)simpleSocketServer:(void *)obj
{
    // You must create a autorelease pool for all secondary threads.
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSMutableData *data = nil;
    int bytesRead, totalBytes;
    NSString *sRecv;
    
    Socket *s = [Socket socket];
    
    [s setBlocking:YES];
    [s listenOnPort:kSimpleSocketTCPPort];
    
    while (simpleSocketKeepAccepting) {
        [s acceptConnection];
        data = [[NSMutableData data] retain];
        totalBytes = 0;
        
        do { 
            bytesRead = [s readDataAndReplace:data];
            totalBytes += bytesRead;
            NSLog(@"NADAMobileIOHelper simpleSocketServer: read %i bytes", bytesRead);
        } while (bytesRead > 0);
        
        //convert to a string
        [data appendBytes:"\0" length:1];
        
        //sRecv = [NSString stringWithUTF8String:(const char*)[data mutableBytes]];
        sRecv = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        
        NSLog(@"Read %i bytes total:", totalBytes);
        NSLog(sRecv);
        
        [sRecv release];
        [data release];
    }

    //and release the pool
    [pool release];
}

/*******************************************************************************************************************
 *
 * P2PMessenger
 *
 */


- (void) setupMessenger:(NSString *)peerID
{
    peerMessenger.myPeerID = [peerID isEqualToString:@""] ? nil : peerID;
}


- (void) messengerAccept:(NSString *)peerID
{
    [self setupMessenger:peerID];
    [peerMessenger startAcceptingWithDelgate:self];
}


- (void) messengerSendTo:(NSString *)toID from:(NSString *)fromID message:(NSString *)msg
{
    [self setupMessenger:fromID];
    [peerMessenger sendData:[msg dataUsingEncoding:NSUTF8StringEncoding] to:toID];
}


- (void) messenger:(P2PMessenger *)messenger didReceiveData:(NSData *)data from:(NSString *)fromID
{
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    [myDelegate nada:self didReceiveFromMessenger:msg from:fromID];
}


@end
